package com.omega.framework.common.util.number;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Objects;

/**
 * 金额工具类
 *
 * @author Lv.
 * @date 2022/11/2 17:33
 */
public class BigDecimalUtil {
    /**
     * @param b1 参数一
     * @param bn 参数二
     * @return 加法结果
     */
    public static BigDecimal safeAdd(BigDecimal b1, BigDecimal... bn) {
        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        if (null != bn) {
            for (BigDecimal b : bn) {
                b1 = b1.add(null == b ? BigDecimal.ZERO : b);
            }
        }
        return b1;
    }

    /**
     * BigDecimal的安全减法运算
     *
     * @param isZero 减法结果为负数时是否返回0，true是返回0（金额计算时使用），false是返回负数结果
     * @param b1     被减数
     * @param bn     需要减的减数数组
     * @return 减法结果
     */
    public static BigDecimal safeSubtract(Boolean isZero, BigDecimal b1, BigDecimal... bn) {
        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        BigDecimal r = b1;
        if (null != bn) {
            for (BigDecimal b : bn) {
                r = r.subtract((null == b ? BigDecimal.ZERO : b));
            }
        }
        return isZero ? (r.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : r) : r;
    }

    /**
     * BigDecimal的安全减法运算
     *
     * @param b1 被减数
     * @param bn 需要减的减数数组
     * @return 减法结果
     */
    public static BigDecimal safeSubtract(BigDecimal b1, BigDecimal... bn) {
        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        BigDecimal r = b1;
        if (null != bn) {
            for (BigDecimal b : bn) {
                r = r.subtract((null == b ? BigDecimal.ZERO : b));
            }
        }
        return r;
    }

    /**
     * BigDecimal的乘法运算封装
     *
     * @param b1 被乘数
     * @param b2 乘数
     * @return 乘法结果
     */
    public static <T extends Number> BigDecimal safeMultiply(T b1, T b2) {
        if (null == b1 || null == b2) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(b1.doubleValue())
                .multiply(BigDecimal.valueOf(b2.doubleValue()))
                .setScale(3, RoundingMode.HALF_UP);
    }

    /**
     * 格式化为经纬度(6位小数)
     */
    public static BigDecimal formatLonLat(Object obj) {
        if (Objects.isNull(obj)) {
            return new BigDecimal("0.000000");
        }

        BigDecimal decimal = null;
        if (obj instanceof BigDecimal) {
            decimal = (BigDecimal) obj;
        } else {
            String val = obj.toString();
            if (!isNumber(val)) {
                return new BigDecimal("0.000000");
            }
            decimal = new BigDecimal(val);
        }

        DecimalFormat format = new DecimalFormat("##.######");
        return new BigDecimal(format.format(decimal));
    }

    public static boolean isNumber(String value) {
        return isInteger(value) || isDouble(value);
    }

    private static boolean isDouble(String value) {
        try {
            Double.parseDouble(value);
            return (value.contains("."));
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private static boolean isInteger(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * before > after 返回true,反之false
     *
     * @param before 第一个
     * @param after  第二个
     * @return boolean
     */
    public static boolean gt(BigDecimal before, BigDecimal after) {
        if (Objects.isNull(before) || Objects.isNull(after)) {
            return false;
        }

        return before.compareTo(after) > 0;
    }

    /**
     * before >= after 返回true,反之false
     *
     * @param before 第一个
     * @param after  第二个
     * @return boolean
     */
    public static boolean ge(BigDecimal before, BigDecimal after) {
        if (Objects.isNull(before) || Objects.isNull(after)) {
            return false;
        }

        return before.compareTo(after) > -1;
    }

    /**
     * before < after 返回true,反之false
     *
     * @param before 第一个
     * @param after  第二个
     * @return boolean
     */
    public static boolean lt(BigDecimal before, BigDecimal after) {
        if (Objects.isNull(before) || Objects.isNull(after)) {
            return false;
        }

        return before.compareTo(after) < 0;
    }


    /**
     * before <= after 返回true,反之false
     *
     * @param before 第一个
     * @param after  第二个
     * @return boolean
     */
    public static boolean le(BigDecimal before, BigDecimal after) {
        if (Objects.isNull(before) || Objects.isNull(after)) {
            return false;
        }

        return before.compareTo(after) < 1;
    }
}
